package Tests;

import Coordinates.Axis;
import Dungeon.CompositeDungeon;
import Dungeon.Level;
import Dungeon.Shaft;
import static org.junit.Assert.*;

import java.math.BigDecimal;

import org.junit.Before;
import org.junit.Test;

import Border.Direction;
import Square.*;

@SuppressWarnings("unused")
public class TestDungeon {
	
	private RegularSquare regularSquare1, regularSquare2, regularSquare3;
	
	private RegularSquareTeleporter regularSquareTeleporter1;
	
	private CompositeDungeon<DefaultSquare> compositeDungeonError, compositeDungeon;
	
	private Level<DefaultSquare> level1, level2, errorLevel;
	
	private Shaft<DefaultSquare> shaft1, shaft2, errorShaft;
	
	@Before
	public void setUp() throws Exception {
		regularSquare1 = new RegularSquare(100, new BigDecimal(20),Direction.EAST);
		regularSquare2 = new RegularSquare(100, new BigDecimal(20),Direction.EAST);
		regularSquare3 = new RegularSquare(100, new BigDecimal(20),Direction.EAST);
		regularSquareTeleporter1 = new RegularSquareTeleporter(20, new BigDecimal(50), Direction.EAST);
		
		compositeDungeon = new CompositeDungeon<DefaultSquare>(15, 15, 15);
		
		level1 = new Level<DefaultSquare>(2, 2);
		level2 = new Level<DefaultSquare>(5, 5);
		
		shaft1 = new Shaft<DefaultSquare>(10, Axis.X_AXIS);
		shaft2 = new Shaft<DefaultSquare>(5, Axis.Y_AXIS);
		
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Constructors_Error1() throws Exception{
		// The length of the shaft is negative, and this is not possible.
			errorShaft = new Shaft<DefaultSquare>(-2, Axis.X_AXIS);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Constructors_Error2() throws Exception{
		// The direction of the shaft is null, this is not possible
		errorShaft = new Shaft<DefaultSquare>(2, null);

	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Constructors_Error3() throws Exception{
		// The dimensions are higher then the previously defined maxDimensions (value = 20)
		compositeDungeonError = new CompositeDungeon<DefaultSquare>(100, 100, 100);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Constructors_Error4() throws Exception{
		// One of the dimensions is lower then 0, this is not possible.
		compositeDungeonError = new CompositeDungeon<DefaultSquare>(-1, 100, 100);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Constructors_Error5() throws Exception{
		// Dimension cannot be negative.
		errorLevel = new Level<DefaultSquare>(-2, 2);
	}

	@Test (expected = IllegalArgumentException.class)
	public void Level_addSquare() throws Exception{
		// A square cannot be added on a negative coordinate.
		level1.addSquare(regularSquare1, -1, 1, 1);

	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Level_addSquare2() throws Exception{
		// A square cannot be added to coordinates larger then the level.
		level1.addSquare(regularSquare1, 3, 3, 1);
	}

	@Test (expected = IllegalArgumentException.class)
	public void Level_addSquare3() throws Exception{
		// A nullpointer cannot be added to the level dungeon.
		level1.addSquare(null, 2, 1, 1);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Shaft_addSquare1() throws Exception{
		// A square cannot be added on negative coordinates
		shaft1.addSquare(regularSquare1, -1, 1, 1);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Shaft_addSquare2() throws Exception{
		// A square cannot be added to coordinates larger then the level.
		shaft2.addSquare(regularSquare1, 11, 1, 1);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Shaft_addSquare3() throws Exception{
		// A square cannot be added when they have a wall in the shaftDirection
		shaft2.addSquare(regularSquare1, 2, 1, 1);
	}
		
	@Test (expected = IllegalArgumentException.class)
	public void Shaft_addSquare4() throws Exception{
		// A square cannot be added when there are two coordinates larger then 1.
		shaft2.addSquare(regularSquare1, 2, 2, 1);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Composite_addDungeon1() throws Exception{
		// A dungeon cannot be a nullpointer.
		compositeDungeon.addDungeon(null, 0, 0, 0);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Composite_addDungeon2() throws Exception{
		// A origin of a dungeon cannot be set outside the predefined dimensions of the composite dungeon.
		compositeDungeon.addDungeon(level1, 16, 0, 0);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Composite_addDungeon3() throws Exception{
		// A dungeon origin cannot be set when one of the coordinates is negative.
		compositeDungeon.addDungeon(level1, -1, 0, 0);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Composite_addDungeon4() throws Exception{
		compositeDungeon.addDungeon(level2, 1, 1, 0);
		// A dungeon cannot be added on a spot where there already is a dungeon located.
		compositeDungeon.addDungeon(level1, 1, 1, 0);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void Composite_addDungeon5() throws Exception{
		compositeDungeon.addDungeon(level1, 0, 0, 0);
		// A dungeon cannot be added again to a certain compositeDungeon.
		compositeDungeon.addDungeon(level1, 4, 3, 3);
	}
	
}
